﻿#define _CRT_SECURE_NO_WARNINGS 1

//#include <stdio.h>
//int main()
//{
//	int a, b, c;
//	a = 5;
//	c = ++a;
//	b = ++c, c++, ++a, a++;
//	b += a++ + c;
//	//a++ 先使用，后++
//	printf("a = %d b = %d c = %d\n:", a, b, c);
//	return 0;
//}

#include<stdio.h>



int main()

{
	int a = 3;
	int b = 2;
	printf("交换前：%d %d\n", a, b);
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("交换后：%d %d\n", a, b);
}

//链接：https://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8
//来源：牛客网
//
//输入一个整数 n ，输出该数32位二进制表示中1的个数。其中负数用补码表示。
//
//数据范围： - 2 ^ {31} <= n <= 2 ^ {31} - 1−2
//31
//<= n <= 2
//31
//−1
//即范围为 : -2147483648 <= n <= 2147483647−2147483648 <= n <= 2147483647

//正解
//int main()
//{
//	int n = 0;
//	int count = 0;
//	int flag = 1;//用1来和n反复做按位与运算
//	scanf("%d", &n);
//	

//	while (flag!=0)
//	{
//		if ( (n&flag) != 0)
//		{
//			count++;
//		}
//		flag = flag << 1;
//	}
//	printf("%d\n", count);
//}

#include<stdio.h>
//static int NumberOf1(int n);
//int main()
//{
//    int n = 0;
//    scanf("%d", &n);
//    int c = NumberOf1(n);
//    printf("%d", c);
//}

static int NumberOf1(int n)
{
    int count = 0;
    int flag = 1;
    while (flag != 0)
    {
	//举个例子
	//n=10;
 	//00000000000000000000000000001010--n的原码
	 
	//01111111111111111111111111110110--n的补码
	
	//00000000000000000000000000000001--flag的原码
	//正数的原码反码补码均相同
	//00000000000000000000000000000001--flag的补码
	//n和flag的补码进行按位与
	//00000000000000000000000000000110--
	//从右边还是，一次左移移位，如果按位与结果不等于0，就得出必等于1，count++
        if ((n & flag) != 0)
        {
            count++;
        }
        flag <<= 1;
    }
    return count;
}



//打印整数二进制的奇数位和偶数位

//获取一个整数二进制序列中所有的偶数位和奇数位，分别打印出二进制序列

//binary(int n)
//{
//	int i = 0;
//	int j = 0;
//	for (i = 31; i>=1; i-=2)//奇数位
//	{
//		int flag = 1;
//		flag = flag << i;
//		if ( (n & flag) != 0)
//		{
//			printf("1");
//		}
//		else
//		{
//			printf("0");
//		}
//	}
//	printf("\n");
//	for (j = 30; j >= 0; j -= 2)//偶数位
//	{
//		int flag = 1;
//		flag = flag << j;
//		if ((n & flag) != 0)
//		{
//			printf("1");
//		}
//		else
//		{
//			printf("0");
//		}
//	}
//}
//
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	binary(n);
//}
// 
//以上是自己写的方法，对比下面老师讲的方法
//之前写代码的时候，从主函数开始写，要写输入计算，输出 - IO型
//接口型，不需要写主函数，默认主函数就是存在的，只需要完成函数就可以了

//输入一个整数 n ，输出该数32位二进制表示中1的个数。其中负数用补码表示。
//常规方法
//int NumberOf1(unsigned int n)
//{
//	int count = 0;
//	while (n)//n的二进制序列
//	{
//	//不管有几个1，一定会循环32次
//		if (n % 2 == 1)
//		{
//			count++;
//		}
//		n = n / 2;
//	}
//	return count;
//}

//最优解
int NumberOf1(unsigned int n)
{
	int count = 0;

	while (n)
	{
		n = n & (n - 1);//每次按位与之后赋值给n，就从右边开始，去掉一个1
		//举个例子：
		//n 10 - 0000000000000000000000000000 1010  --1号 
		//正数的原码反码补码均相同
	   //n-1 9 - 0000000000000000000000000000 1001       
 
 	  //n&(n-1)- 0000000000000000000000000000 1000  --3号  n=n&(n-1)
		//可以发现，按位与之后，对比1号和3号，最右边的1不见了，然后把3号的结果赋给n
		//继续
		//n    - 0000000000000000000000000000 1000  
	  //n-1    - 0000000000000000000000000000 0111
    //n&(n-1)- 0000000000000000000000000000 0000 --5号
		//对比3号和5号，右边的1又不见了
	  //此时n为0，退出循环
 
		//二进制中有几个1，就返回几次count
		//有几个1，就循环几次
		count++;
	}
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	
	int ret = NumberOf1(n);
	
	printf("%d", ret);

}

//能不能写个代码，判断n是不是2的k次方？
//只要是2的k次方的数字，2进制表示中一定只有1个1
//if (n & (n - 1) == 0)
//{	  //每次按位与一次之后，都会把一个1去掉
//	printf("是2的k次方\n");
//}

//获取一个整数二进制序列中所有的偶数位和奇数位，分别打印出二进制序列

//最优解
void Print(int n)
{
	int i = 0;
	printf("奇数位：");
	for (i = 30; i >=0; i -= 2)
	{
		printf("%d", (n >> i) & 1);
		//算术右移（对于有符号位的来说），右边丢掉，左边补符号位
		//逻辑右移（对于无符号的来说），右边丢掉，左边补符号位
		//每右移一位，然后与1按位与，从而判断这一位是否为1，为1打印，为0也打印
		
	}
	printf("\n");
	printf("偶数位：");
	for (i = 31; i >= 1; i -= 2)
	{
		printf("%d", (n >> i) & 1);
	}
	return 0;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	Print(n);
	//打印n的2进制中的所有奇数位和偶数位
	return 0;

}

求两个数二进制中不同位的个数
两个int（32位）整数m和n的二进制表达中，有多少个位(bit)不同？
int count_diff_one(int m, int n)
{
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if (((m >> i) & 1) != ((n >> i) & 1))
		{
			count++;//统计二进制中有几个1
		}
	}
	return count;
}

//异或操作符--相同为0，相异为1
int count_diff_one(int m, int n)
{
	int tmp = m ^ n;
	int count = 0;
	//统计tmp的二进制中有几个1
	while (tmp)
	{
		tmp = tmp & (tmp - 1);
		count++;
	}
	return count;
}
//这个为自己写的

int main()
{
	int m = 0;
	int n = 0;
	scanf("%d%d", &m, &n);
	int ret = count_diff_one(m, n);
	printf("%d\n", ret);
	return 0;

}

青蛙跳台阶
小乐乐上课需要走n阶台阶，因为他腿比较长，所以每次可以选择走一阶或者走两阶，那么他一共有多少种走法？

输入描述：
输入包含一个整数n(1 ≤ n ≤ 30)
输出描述：
输出一个整数，即小乐乐可以走的方法数。
示例1
输入：
2
复制
输出：
2
复制
示例2
输入：
10
复制
输出：
89
int  Fib(int n)
{
	if (n <= 2)
	{
		return n;
	}
	else
	{
		return Fib(n - 1) + Fib(n - 2);
	}
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}

//KiKi想获得某年某月有多少天，请帮他编程实现。输入年份和月份，计算这一年这个月有多少天。


int get_days_of_month(int y, int m)
{
	int days[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31 };
	//                 1  2 3   4  5  6  7  8  9 10 11 12
	int day = days[m];
	if ((m == 2) && ((y % 4 != 0) && (y % 100 == 0)) || (y % 400 != 0))
	{
		day++;
	}
	return day;
}

int main()
{
	int y = 0;
	int m = 0;
	while (scanf("%d%d", &y, &m) == 2)
	{
		int ret = get_days_of_month(y, m);
		printf("%d", ret);
	}
}

//sizeof的计算结果是无符号的正数
//unsigned int 就是signed_t，就是无符号整型 
//size_t  -- 是sizeof计算的结果的类型

//char short int long
//short--默认是signed short
//int --默认是signed int
//long --默认是signed long

//唯独char，到底是signed char 还是unsigned char是取决于编译器的
//不过常见的编译器，char都是signed char
//目前所见过的编译器，都是signed char

//输入NxM矩阵，矩阵元素均为整数，计算其中大于零的元素之和。
//
//输入描述：
//第一行为N M(N: 矩阵行数；M: 矩阵列数, 且M, N <= 10)，接下来的N行为矩阵各行。
//输出描述：
//一行，其中大于零的元素之和。
//示例1
//输入：
//3 3
//2 3 4
//- 5 - 9 - 7
//0 8 - 4
//复制
//输出：
//17

int main()
{
	int n = 0;
	int m = 0;
	scanf("%d%d", &n, &m);
	int j = 0;
	//int arr[10][10] = { 0 };//没必要存进去
	int i = 0;
	int tmp = 0;
	int sum = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < m; j++)
		{
			scanf("%d", &tmp);
			if (tmp > 0)
			{
				sum += tmp;
			}
		}
	}
	printf("%d", sum);
	return 0;
}

小乐乐在课上学习了二进制八进制与十六进制后，对进制转换产生了浓厚的兴趣。因为他的幸运数字是6，所以他想知道一个数表示为六进制后的结果。请你帮助他解决这个问题。

输入描述：
输入一个正整数n(1 ≤ n ≤ 109)

输出描述：
输出一行，为正整数n表示为六进制的结果

int main()
{
	int arr[20] = { 0 };
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	while (n)
	{
		arr[i++] = n % 6;
		n /= 6;
		
	}
	for (i--; i >= 0; i--)
	{
		printf("%d", arr[i]);
	}
	return 0;
}

递归
void Print(int n)
{
	if (n > 5)
 {
		Print(n / 6);
	}
 printf("%d", n % 6);
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	Print(n);
}

KiKi有一个矩阵，他想知道转置后的矩阵（将矩阵的行列互换得到的新矩阵称为转置矩阵），请编程帮他解答。

输入描述：
第一行包含两个整数n和m，表示一个矩阵包含n行m列，用空格分隔。(1≤n≤10, 1≤m≤10)

从2到n + 1行，每行输入m个整数（范围 - 231~231 - 1），用空格分隔，共输入n * m个数，表示第一个矩阵中的元素。

输出描述：
输出m行n列，为矩阵转置后的结果。每个数后面有一个空格。


int main()
{
	int n = 0;
	int m = 0;
	scanf("%d%d", &n, &m);
	int arr[n][m];
	int i = 0;
	int j = 0;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < m; j++)
		{
			scanf("%d", &arr[i][j]);
			//输入
		}
	}
	//打印
	for(i=0;i<m;i++)
	{
		for (j = 0; j < n; j++)
		{
			printf("%d", arr[j][i]);
		}
		printf("\n");
	}
}

有一个整数序列（可能有重复的整数），现删除指定的某一个整数，输出删除指定数字之后的序列，序列中未被删除数字的前后位置没有发生改变。

数据范围：序列长度和序列中的值都满足 1 \le n \le 501≤n≤50
输入描述：
第一行输入一个整数(0≤N≤50)。

第二行输入N个整数，输入用空格分隔的N个整数。

第三行输入想要进行删除的一个整数。

输出描述：
输出为一行，删除指定数字之后的序列。

//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int arr[n];
//	int i = 0;
//	for (i = 0; i < n; i++)
//	{
//		scanf("%d", &arr[i]);
//	}
//	//输入删除的数字
//	int del = 0;
//	scanf("%d", &del);
//}
////投机取巧的写法
//
////真正的把数组的元素删除
////所谓删除，就是把后面的元素往前面覆盖就可以了
//
int main()
{
	int n = 0;
	scanf("%d", &n);
	int arr[n];
	int i = 0;
	for (i = 0; i < n; i++ )
	{
		scanf("%d", &arr[i]);
	}
	int del = 0;
	scanf("%d", &del);
	int j = 0;
	for (i = 0; i < n; i++)
	{
		if (arr[i] != del)
		{
			arr[j++] = arr[i];
		}
	}
	for (i = 0; i < j; i++)
	{
		printf("%d ", arr[i]);
	}
}

// 例如
//00000000000000000000000000001010
//void Print(int n )
//{
//	//假设右边定为第1位
//	int i = 0;
//	printf("偶数位为：");
//	for (i = 31; i >= 1; i -= 2)//打印偶数位
//	{
//		printf("%d", (n >> i) & 1);
//	}
//	printf("\n");
//	printf("奇数位为：");
//	for (i = 30; i >= 0; i -= 2)//打印奇数位
//	{
//		printf("%d", (n >> i) & 1);
//	}
//}
//
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	Print(n);
//	return 0;
//}

//输入两个整数，求两个整数二进制格式有多少个位不同
//输入描述:
//两个整数
//输出描述 :
//二进制不同位的个数
//示例1
//输入
//22 33
//输出
//5
//int count_diff_one(int m, int n)
//{
//	int i = 0;
//	int count = 0;
//	for (i = 31; i >= 0; i--)
//	{
//		if (((m >> i) & 1) != ((n >> i) & 1) )
//		{
//			count++;
//		}
//	}
//	return count;
//}
//
//int main()
//{
//	int n = 0;
//	int m = 0;
//	scanf("%d%d",&m, &n);
//	int ret = count_diff_one(m, n);
//	printf("%d", ret);
//
//}

//小乐乐上课需要走n阶台阶，因为他腿比较长，所以每次可以选择走一阶或者走两阶，那么他一共有多少种走法？
//n=1时，sum=1，n=2时，sum = 2，n>2时，sum = Fib（n-1）+ Fib(n-2)

//int Fib(int n)
//{
//	if (n <= 2)
//	{
//		return n;
//	}
//	else
//	{
//		return Fib(n - 1) + Fib(n - 2);
//	}
//}
//int main()
//{
//	int n = 0;
//	scanf("%d", &n);
//	int ret = Fib(n);
//	printf("%d", ret);
//}

//KiKi想获得某年某月有多少天，请帮他编程实现。输入年份和月份，计算这一年这个月有多少天。
//输入描述：
//多组输入，一行有两个整数，分别表示年份和月份，用空格分隔。
//输出描述：
//针对每组输入，输出为一行，一个整数，表示这一年这个月有多少天。
//示例1
//输入：
//2008 2
//复制
//输出：
//29

int main()
{
	int y = 0;
	int m = 0;
	int day = 0;
	int arr[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
				  // 1  2  3 4   5  6  7  8  9 10 11 12	
	while (scanf("%d%d", &y, &m) == 2)
	{
		if (m == 2)
		{
			if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
			{
				day = arr[m] + 1;
			}
			else
			{
				day = arr[m];
			}
		}
		else
		{
			day = arr[m];
		}
		printf("%d\n", day);
	}
	
}

//int main()
//{
//	int* tmp;
//	int a = 4, b = 3,*p1 = &a, * p2 = &b;
//	tmp = *p1;
//	*p1 = *p2;
//	*p2 = tmp;
//	printf("%d,%d\n", a, b);
//	printf("%d,%d\n", *p1, *p2);
//}
//int swap(int* a, int* b)
//{
//	int tmp = *a;
//	*a = *b;
//	*b = tmp;
//}
//
//int main()
//{
//	int a = 3;
//	int b = 4;
//	printf("交换前：%d %d\n", a, b);
//	swap(&a, &b);
//	printf("交换后：%d %d\n", a, b);
//}

//int main()
//{
//	int a[5], *p=a, i;
//	for (i = 0; i < 5; i++)
//	{
//		scanf("%d", p + i);
//	}
//	for (i = 0; i < 5; i++, p++)
//	{
//		printf("%d", *p);
//	}
//}

//#include <stdio.h>
//int i;
//int main()
//{
//    i--;//-1
//    if (i > sizeof(i))
//    {  //-1>4? 不，由于signed（i）计算的是i的空间大小，默认是无符号类型,即unsigned int
//        //，但是-1是有符号类型，故由算术转换可知
//        //有符号类型-1会向上提升为无符号整型，-1的二进制位是一个很大的数，远远大于sizeof（i）--4,故输出>
//        printf(">\n");
//    }
//    else
//    {
//        printf("<\n");
//    }
//    return 0;
//}

输入NxM矩阵，矩阵元素均为整数，计算其中大于零的元素之和。

输入描述：
第一行为N M(N: 矩阵行数；M: 矩阵列数, 且M, N <= 10)，接下来的N行为矩阵各行。
输出描述：
一行，其中大于零的元素之和。
示例1
输入：
3 3
2 3 4
- 5 - 9 - 7
0 8 - 4
复制
输出：
17

int main()
{
	int n = 0;//控制行
	int m = 0;//控制列
	scanf("%d%d", &n, &m);
	int i = 0;
	int j = 0;
	int input = 0;
	int sum = 0;
	for (i = 0; i < n;i++)
	{
		for (j = 0; j < m; j++)
		{
			scanf("%d", &input);
			if (input > 0)
			{
				sum += input;
			}
		}
	}
	printf("%d", sum);

}

//小乐乐在课上学习了二进制八进制与十六进制后，对进制转换产生了浓厚的兴趣。因为他的幸运数字是6，所以他想知道一个数表示为六进制后的结果。请你帮助他解决这个问题。
//
//输入描述：
//输入一个正整数n(1 ≤ n ≤ 109)
//
//输出描述：
//输出一行，为正整数n表示为六进制的结果
//示例1
//输入：
//6
//复制
//输出：
//10
//复制
//示例2
//输入：
//120
//复制
//输出：
//320
//int main()
//{
//    int n = 0;
//    int i = 0;
//    int arr[100] = { 0 };
//    scanf("%d", &n);
//    while (n)
//    {
//        arr[i++] = n % 6;
//        n /= 6;
//    }
//    for (i--; i >= 0; i--)
//    {
//        printf("%d", arr[i]);
//    }
//}

//描述
//KiKi有一个矩阵，他想知道转置后的矩阵（将矩阵的行列互换得到的新矩阵称为转置矩阵），请编程帮他解答。
//
//输入描述：
//第一行包含两个整数n和m，表示一个矩阵包含n行m列，用空格分隔。(1≤n≤10, 1≤m≤10)
//
//从2到n + 1行，每行输入m个整数（范围 - 231~231 - 1），用空格分隔，共输入n * m个数，表示第一个矩阵中的元素。
//
//输出描述：
//输出m行n列，为矩阵转置后的结果。每个数后面有一个空格。
//示例1
//输入：
//2 3
//1 2 3
//4 5 6
//复制
//输出：
//1 4
//2 5
//3 6

//int main()
//{
//	int n = 0;//行
//	int m = 0;//列
//	int i = 0;
//	int j = 0;
//	scanf("%d%d", &n, &m);
//	int arr[n][m] = { 0 };
//	for (i = 0; i < n; i++)
//	{
//		for (j = 0; j < m; j++)
//		{
//			scanf("%d", &arr[i][j]);
//		}
//	}
//	for (i = 0; i < m; i++)
//	{
//		for (j = 0; j < n; j++)
//		{
//			printf("%d", arr[j][i]);
//		}
//	}
//}

//有一个整数序列（可能有重复的整数），现删除指定的某一个整数，输出删除指定数字之后的序列，序列中未被删除数字的前后位置没有发生改变。
//
//数据范围：序列长度和序列中的值都满足 1 \len \le 501≤n≤50
//输入描述：
//第一行输入一个整数(0≤N≤50)。
//
//第二行输入N个整数，输入用空格分隔的N个整数。
//
//第三行输入想要进行删除的一个整数。
//
//输出描述：
//输出为一行，删除指定数字之后的序列。
//示例1
//输入：
//6
//1 2 3 4 5 9
//4
//复制
//输出：
//1 2 3 5 9
//复制
//示例2
//输入：
//5
//1 2 3 4 6
//5
//复制
//输出：
//1 2 3 4 6
//所谓删除，就是将后面的数覆盖在前面要删除的数上面

int main()
{
	int n = 0;
	int arr1[50] = { 0 };
	scanf("%d", &n);
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr1[i]);
	}
	int del = 0;//要删除的数字
	scanf("%d", &del);
	int j = 0;
	//用来存储不需要删的元素
	for(i=0;i<n;i++)
	{
		if (arr1[i] != del)
		{
			arr1[j++] = arr1[i];
		}//每次判断是否为要删除的元素，如果不是，就不动它
	}
	
	for (i = 0; i < j; i++)
	{
		printf("%d", arr1[i]);
	}
}

